package socket;

import java.io.*;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

public class Client_v3 {
    private Socket socket;
    /*
    * 初始化客户端
    * java.net.Socket 套接字
    * Socket封装了TCP协议的通讯细节，使用它可以通过网络与远程计算机进行TCP链接，并基于两条流(输入与输出)与远程计算机通讯*/
    public Client_v3(){
        try {
            /*
            *实例化Socket时需要传入两个参数用于远程计算机建立连接。
             * 实例化的过程就是与远程计算机建立连接的过程
             * 如果实例化成功说明与远端计算机建立连接。如果建立连接失败则会抛出异常
             * 参数1：远程计算机的IP地址
             * 参数2：远程计算机上的服务端程序开启的服务端口
             * 我们通过IP可以找到网络上服务端所在的计算机，通过端口找到该计算机上运行的服务端应用程序*/
            System.out.println("正在连接服务器...");
            socket = new Socket("localhost",8088);
            System.out.println("与服务器成功连接！");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /*
    * 客户端开始工作
    */
    public void start(){
        try {
            //启动线程用于读取服务器发送过来的消息
            ServerHandler serverHandler = new ServerHandler();
            Thread t = new Thread(serverHandler);
            t.setDaemon(true);
            t.start();
            /*
            * socket提供的重要方法
            * OutputStream getOutputStream()
            * 通过socket获取的字节输出流写出的数据就会发送给与之连接的远端计算机*/
            OutputStream out = socket.getOutputStream();
            OutputStreamWriter osw = new OutputStreamWriter(out, StandardCharsets.UTF_8);
            BufferedWriter bw = new BufferedWriter(osw);
            PrintWriter pw = new PrintWriter(bw,true);
            Scanner scanner = new Scanner(System.in);
            while (true){
                String line = scanner.nextLine();
                if("exit".equalsIgnoreCase(line)){
                    break;
                }
                pw.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
                //最终交互完毕后，要断开连接
            try {
                //close方法内部会进行TCP的四次挥手操作
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        Client_v3 client = new Client_v3();
        client.start();
    }
    /*该线程负责读取来自服务端发送过来的消息*/
    public class ServerHandler implements Runnable{
        public void run(){
            try {
                InputStream in = socket.getInputStream();
                InputStreamReader isr = new InputStreamReader(in,StandardCharsets.UTF_8);
                BufferedReader br = new BufferedReader(isr);
                String line;
                while ((line=br.readLine())!=null){
                    System.out.println(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
